// metrics data structure
//基本功能 inc/dec/snapshot
use std::collections::HashMap;
use std::fmt::{Display, Formatter};
use std::ops::Deref;
use std::sync::{Arc, RwLock};

#[derive(Debug, Clone)]
pub struct MetricsOri {
    pub data: Arc<RwLock<HashMap<String, i64>>>,
}

impl Default for MetricsOri {
    fn default() -> Self {
        Self::new()
    }
}

impl MetricsOri {
    pub fn new() -> MetricsOri {
        MetricsOri {
            data: Arc::new(RwLock::new(HashMap::new())),
        }
    }
    #[allow(dead_code)]
    pub fn inc(&self, key: impl Into<String>) {
        let mut guard = self.data.write().unwrap();
        let counter = guard.entry(key.into()).or_insert(0);
        *counter += 1;
    }

    #[allow(dead_code)]
    pub fn des(&self, key: impl Into<String>) {
        let mut guard = self.data.write().unwrap();
        let counter = guard.entry(key.into()).or_insert(0);
        *counter -= 1;
    }

    #[allow(dead_code)]
    pub fn snapshot(&self) -> HashMap<String, i64> {
        let guard = self.data.read().unwrap();
        guard.deref().clone()
    }
}

impl Display for MetricsOri {
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
        let data = self.data.read().unwrap();
        for (k, v) in data.iter() {
            writeln!(f, "{k}: {v}")?;
        }
        Ok(())
    }
}
